package edu.strategy.single.scanned;

import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

import robocode.AdvancedRobot;
import robocode.Event;
import robocode.ScannedRobotEvent;
import edu.strategy.single.Single;

public class TeancumPassiveScannedStrategy extends Single{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	static double currentEnergy;
	static int distanceindex;
	static double[] benefit = new double[30], penalty = new double[30];
	long nextTime;
	static double currentVBound;
	static double currentDirection=40;
	
	public TeancumPassiveScannedStrategy(AdvancedRobot advancedRobot) {
		super(advancedRobot);
	}

	@Override
	public void prepare() {
		currentEnergy = super.getAdvancedRobot().getEnergy();
	}
	
	@Override
	public void work() {
		super.getAdvancedRobot().fire(1);
	}

	@Override
	public void work(Event e) {
		super.used();
		ScannedRobotEvent srv = (ScannedRobotEvent) e;
		
		double distance = srv.getDistance();
		distanceindex = (int)(distance/50);
		double denergy = currentEnergy-srv.getEnergy();
		super.getAdvancedRobot().setTurnRadarLeft(super.getAdvancedRobot().getRadarTurnRemaining());
		if (denergy >= .09 && denergy <= 3)
		{
			benefit[distanceindex] += denergy;
			if (super.getAdvancedRobot().getTime() >= nextTime)
			{
				currentVBound = 2+10*Math.random();//Math.sqrt(Math.random()*80);
				currentDirection *= (Math.random() < .4)?-1:1;
				nextTime = super.getAdvancedRobot().getTime()+(long)(distance/(20-3*denergy)*Math.random());
			}
		}
		else if (super.getAdvancedRobot().getTime() >= nextTime)
			currentVBound -= Math.random()*3-2;
		else if (Math.random() < .01)
		{
			nextTime -= (nextTime-super.getAdvancedRobot().getTime())/2;
			currentVBound = 0;
		}
		currentEnergy = srv.getEnergy();
		double mindist = findDistanceBracket();
		double rel;
		double absbearing = super.getAdvancedRobot().getHeadingRadians()+srv.getBearingRadians();
		if (distance < mindist && distance > mindist-120 && (distanceFromCorner()>200 || distanceFromCorner() > distance))
			rel = Math.PI/2;
		else if ((distance > mindist || distanceFromCorner() < 200 || out(absbearing + Math.PI, 50)) == currentDirection > 0)
			rel = Math.PI/3;
		else
			rel = 2*Math.PI/3;
		super.getAdvancedRobot().setTurnRightRadians(robocode.util.Utils.normalRelativeAngle(srv.getBearingRadians()-rel));
	}
	
	public double findDistanceBracket()
	{
		int bestindex;
		int i = bestindex = 8;
		do
		{
			if (findBenefit2(i) > findBenefit2(bestindex))
				bestindex = i;
			i++;
		}
		while (i <= 14);
		return 800;
	}
	
	public double findBenefit2(int index)
	{
		return 2*findBenefit(index)+findBenefit(index-1)+findBenefit(index+1);
	}
	
	public double findBenefit(int index)
	{
		return (benefit[index]-penalty[index])/(benefit[index]+penalty[index]);
	}
	private double distanceFromCorner()
	{
		double min = Double.POSITIVE_INFINITY;
		int i=0;
		do
		{
			min = Math.min(min, Point2D.distance(super.getAdvancedRobot().getX(), super.getAdvancedRobot().getY(), (i&1)*super.getAdvancedRobot().getBattleFieldWidth(), (i>>1)*super.getAdvancedRobot().getBattleFieldHeight()));
			i++;
		}
		while (i < 4);
		return min;
	}
	public boolean out(double angle, double c)
	{
		return !(new Rectangle2D.Double(18, 18, super.getAdvancedRobot().getBattleFieldWidth()-36D,  super.getAdvancedRobot().getBattleFieldHeight()-36D)).contains(Math.sin(angle)*c+super.getAdvancedRobot().getX(), Math.cos(angle)*c+super.getAdvancedRobot().getY());
	}

	@Override
	public String toString() {
		return "TeancumPassiveScannedStrategy";
	}
}
